<?php
/**
 * +------------------------------
 * Created by PhpStorm.
 * +------------------------------
 * User: xxx
 * +------------------------------
 * DateTime: 2019/12/6 20:34
 * +------------------------------
 */

namespace Core\annotationhandlers;

use Core\annotations\RequestMapping;
use Core\BeanFactory;
use Core\init\DecoratorCollector;
use Core\init\RouterCollect;


return [
    /**
     * @var RouterCollect $router_collect
     */
    RequestMapping::class => function (\ReflectionMethod $method, $instance, $self) {

        $path = $self->value;
        $request_method = count($self->method) > 0 ? $self->method : ['GET'];

        /**
         * 处理路由收集器
         */
        $router_collect = BeanFactory::getBean(RouterCollect::class);
        $router_collect->addRouter($request_method, $path, function (array $params, array $ext_params) use ($method, $instance) {
            //return $method->invoke($instance); // 执行反射方法并返回

            //带参数传递
            $inputParams = [];
            $ref_params = $method->getParameters(); //取得发射方法的参数列表
            foreach ($ref_params as $ref_param) {
                //判断的目的：防止注解中的参数和方法上的参数不一致
                if (isset($params[$ref_param->getName()])) {
                    $inputParams[] = $params[$ref_param->getName()];
                } else {

                    foreach ($ext_params as $ext_param) { // ext_params 都是实例对象  如request response

                        //判断类型
                        if ($ref_param->getClass()->isInstance($ext_param)) {
                            $inputParams[] = $ext_param;
                            goto end;  //找到实例对象，则跳出内层循环，在end：点后，继续执行外层foreach
                        }

                    }

                    $inputParams[] = null;
                }

                end: // 跳出点标识
            }

//            return $method->invokeArgs($instance, $inputParams);

            //TODO:装饰器方法执行
            /**
             * @var  $d_collector DecoratorCollector
             */
            $d_collector = BeanFactory::getBean(DecoratorCollector::class);
            return $d_collector->exec($method, $instance, $inputParams);

        });

        return $instance;
    },

];
































